#include "clientHead/epoll.h"
#include "clientHead/order_analyse.h"
#include "clientHead/trans_file.h"
#include "clientHead/sys.h"

void handler(int signum){
    printf("Signum = %d\n", signum);
}

void getMd5(char* filename, char *mdStr){
    int fd = open(filename, O_RDONLY);
    char buf[4096];

    MD5_CTX c;  //创建一个MD5类型的变量c
    MD5_Init(&c);//把MD5的值取出来放到变量c里面
    //循环读取文件内容
    while(1)
    {
        //每一次都清空buf、然后读文件
        bzero(buf,sizeof(buf));
        ssize_t sret = read(fd,buf,sizeof(buf));
        if(sret == 0) break;
        //从buf里读到变量c中，读sret个字节
        MD5_Update(&c,buf,sret);
    }
    //md里面存储了md5的二进制形式
    unsigned char md[16];
    MD5_Final(md,&c);
    //把MD5的值打印出来
    for (int i = 0; i < 16; i++) {
        sprintf(&mdStr[i * 2], "%02x", (unsigned int)md[i]);
    }
}
void putFile(int sockfd,char* filename);

int main(int argc, char *argv[])
{
    ARGS_CHECK(argc, 3);
    signal(SIGPIPE, handler);
    order_train_t* orderTrain = (order_train_t*)calloc(1, sizeof(order_train_t));
    order_train_t* retTrain = (order_train_t*)calloc(1, sizeof(order_train_t));
    
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(atoi(argv[2]));
    servaddr.sin_addr.s_addr = inet_addr(argv[1]);
    
    int ret = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    ERROR_CHECK(ret, -1, "client connect");

    int epfd = epoll_create(1);
    epollAdd(epfd, STDIN_FILENO);
    epollAdd(epfd, sockfd);
    struct epoll_event readySet[2];
    char command[] = "请输入您的指令>>  ";
    char filename[256]={0};
    while(1){
        write(STDOUT_FILENO, command, strlen(command));
        int readyNum = epoll_wait(epfd, readySet, 2, -1);
        for(int i = 0; i < readyNum; ++i){
            if(readySet[i].data.fd == STDIN_FILENO){
                bzero(orderTrain, sizeof(order_train_t));
                read(STDIN_FILENO, orderTrain->train_data, sizeof(orderTrain->train_data));                       
                int ret = order_judg(orderTrain->train_data, orderTrain);
                if(ret  == -1){
                    break;
                }
                if(orderTrain->order_len==ORDER_PUTS){
                    char buf[32];
                    getMd5(orderTrain->train_data,buf);
                    printf("111111 buf = %s\n", buf);
                    strcpy(filename,orderTrain->train_data);
                    strcat(orderTrain->train_data,"/");
                    strcat(orderTrain->train_data,buf);
                    orderTrain->data_len=strlen(orderTrain->train_data);
                }
                printf("train_data:%s\n", orderTrain->train_data);
                sendTrain(sockfd, orderTrain);
            }
            else if(readySet[i].data.fd == sockfd){
                
                bzero(retTrain, sizeof(order_train_t));
                ret = recvTrain(sockfd, retTrain);
                printf("%s\n", retTrain->train_data);
                if(strcmp(retTrain->train_data,"yes")==0){
                    putFile(sockfd,filename);
                }
                int sret = strcmp(retTrain->train_data, "error");
                printf("sret = %d\n",sret);
                if(sret != 0){
                    printf("接收到消息:%s\n", retTrain->train_data);
                }
                // clientExecute();
            }
        }
    }
END:
    close(sockfd);
    return 0;
}

void putFile(int sockfd,char* filename){
    int fd=open(filename,O_RDWR);
    struct stat statbuf;
    fstat(fd,&statbuf);
    int len=sizeof(statbuf.st_size);
    send(sockfd,&len,sizeof(int),MSG_NOSIGNAL);
    send(sockfd,&statbuf.st_size,len,MSG_NOSIGNAL);
    sendfile(sockfd,fd,NULL,statbuf.st_size);
    close(fd);
}
